using UnityEngine;
using System.Collections.Generic;

// Column of Ladder
public class LadderColumn : MonoBehaviour 
{
	public const float Depth = -2f;
	
	private int m_posX;
	private int m_posStartY;
	private int m_posEndY;
	
	private Vector3 m_pointStart;
	private Vector3 m_pointEnd;
	
	private List<LadderRung> m_listLadderRung = null; // sorted by posY (on node of this column side)
	
	private LineRenderer m_renderer = null;
	private Color m_color = Color.gray;
	private float m_width = 5f;
	
	public int PosX
	{
		get { return m_posX; }
	}
	
	public Vector2 StartPoint
	{
		get { return new Vector2((float)m_posX, (float)m_posStartY); }
	}
	
	public Vector2 EndPoint
	{
		get { return new Vector2((float)m_posX, (float)m_posEndY); }
	}
	
	static public LadderColumn Create(int posX, int posStartY, int posEndY)
	{
		string objName = "LadderColumn_";
		objName += (posX < 0 ? "n" : "p");
		objName += Mathf.Abs(posX).ToString();
		
		GameObject ladderColumnObject = new GameObject(objName);
		ladderColumnObject.AddComponent<LineRenderer>();
		LadderColumn ladderColumn = ladderColumnObject.AddComponent<LadderColumn>();
		ladderColumn.Initialize(posX, posStartY, posEndY);
		return ladderColumn;
	}
	
	// Initialization
	private void Initialize(int posX, int posStartY, int posEndY)
	{
		m_posX = posX;
		m_posStartY = posStartY;
		m_posEndY = posEndY;
		
		m_pointStart = new Vector3((float)m_posX, (float)m_posStartY, Depth);
		m_pointEnd = new Vector3((float)m_posX, (float)m_posEndY, Depth);

		m_listLadderRung = new List<LadderRung>();
		
		m_renderer = GetComponent<LineRenderer>();
		if (m_renderer)
		{
			m_renderer.material = Material.Instantiate(Resources.Load("Materials/Column_Material")) as Material;
			m_renderer.SetColors(m_color, m_color);
			m_renderer.SetWidth(m_width, m_width);
			m_renderer.SetVertexCount(2);
			m_renderer.SetPosition(0, m_pointStart);
			m_renderer.SetPosition(1, m_pointEnd);
		}
		else
		{
			Debug.LogError("Not found LineRenderer component : " + m_posX);
		}
	}
	
	private void Update()
	{
		if (m_renderer)
		{
			m_renderer.SetPosition(0, m_pointStart);
			m_renderer.SetPosition(1, m_pointEnd);
		}
	}
	
	public void AddLadderRung(LadderRung addRung)
	{
		int newPosY;
		if (addRung.TryGetPosY(m_posX, out newPosY) == false)
		{
			Debug.LogError("addRung is not match with this LadderColumn.m_posX ( " + m_posX + " )");
		}
		
		if (newPosY >= m_posStartY || newPosY <= m_posEndY)
		{
			Debug.LogError("addRung's posY is not allow range ( " + newPosY + " )");
		}
		
		int count = m_listLadderRung.Count;		
		int posY;
		for (int i = 0; i < count; ++i)
		{
			if (m_listLadderRung[i].TryGetPosY(m_posX, out posY) == false)
			{
				Debug.LogError("LadderRung List is broken. Data is wrong!!");
			}
			
			if (newPosY == posY)
			{
				Debug.LogError(posY + " posY LadderRung is exist allready.");
			}
			
			if (newPosY > posY)
			{
				m_listLadderRung.Insert(i, addRung);
				return;
			}
		}
		
		m_listLadderRung.Add(addRung);
	}
	
	public bool IsExistRung(int posY)
	{
		int rungPosY = 0;
		foreach(LadderRung ladderRung in m_listLadderRung)
		{
			if (ladderRung.TryGetPosY(m_posX, out rungPosY))
			{
				if (posY == rungPosY)
				{
					return true;
				}
			}
		}
		
		return false;
	}
	
	public Vector3 GetClosestPoint(Vector3 point)
	{
		point.z = Depth;
		Vector3 closestPoint = MathUtils.GetClosestPoint(m_pointStart, m_pointEnd, point);
		closestPoint.x = (float)m_posX;
		closestPoint.z = Depth;
		return closestPoint;
	}
	
	public void ClearLadderRungs()
	{
		m_listLadderRung.Clear();
	}
	
	public int GetNextLadderRung(int posY)
	{
		return -1;
	}
	
	/*
	private void Sort()
	{
		m_listLadderRung.Sort
		(
			delegate(LadderRung rung1, LadderRung rung2)
			{
				float p1 = rung1.GetPositionY(m_posX);
				float p2 = rung2.GetPositionY(m_posX);
				
				System.Diagnostics.Debug.Assert(float.IsNaN(p1) == false && float.IsNaN(p2) == false);
				
				return p2.CompareTo(p1);
			}
		);
	}
	*/
}
